// #include <iostream>
// #include <unistd.h>
// #include <thread>
// using std::cout;
// using std::endl;

// // 任何语言，在linux中如果要实现多线程，必定要是用pthread库
// // 如何看待C++11中的多线程呢？？C++11 的多线程，在Linux环境中，本质是对pthread库的封装！
// void thread_run()
// {
//     while (true)
//     {
//         //printf("我是新线程\n");
//         cout << "我是新线程..." << endl;
//         cout.flush();
//         sleep(1);
//     }
// }
// int main()
// {
//     std::thread t1(thread_run);

//     while (true)
//     {
//         //printf("我是主线程\n");
//         cout << "我是主线程..." << endl;
//         cout.flush();

//         sleep(1);
//     }
//     t1.join();
//     return 0;
// }

#include <iostream>
#include <string>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <cstdlib>
#include <cassert>
using namespace std;

class ThreadDate
{
public:
    int number;
    pthread_t tid;
    char namebuffer[64];
};

void *start_routine(void *argv) // 拷贝td，形参是实参的一份临时拷贝
{
    // sleep(1);
    ThreadDate *td = static_cast<ThreadDate *>(argv);
    int cnt = 10;
    while (cnt)
    {
        // cout << "thread name is : " << td->namebuffer << "cnt:" << cnt-- << endl;
        cout << "cnt : " << cnt << " &cnt :" << &cnt << endl;
        cout.flush();

        cnt--;
        sleep(1);
        // return nullptr;
        //  pthread_exit(nullptr);
    }
    // delete td;
    // return (void *)td->number;
    return (void *)106;
}

int main()
{
    vector<ThreadDate *> vp;
#define NUM 10
    for (size_t i = 0; i < NUM; ++i)
    {
        ThreadDate *td = new ThreadDate();
        td->number = i + 1;
        snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i);
        pthread_create(&td->tid, nullptr, start_routine, td); // 这里传td
        vp.push_back(td);
    }

    for (auto &iter : vp)
    {
        cout << "create thread: " << iter->namebuffer << " : " << iter->tid << " suceesss" << endl;
        cout.flush();
    }
    sleep(5);
    for (auto &iter : vp) // 线程全部取消，如果上面是死循环，那么下面的join就会一直阻塞
    {
        pthread_cancel(iter->tid);
        cout << "pthread_cancle" << iter->namebuffer << "success" << endl;
        cout.flush();
    }
    for (auto &iter : vp)
    {
        void *ret = nullptr;                   // 这里是void *
        int n = pthread_join(iter->tid, &ret); //&ret —— void**
        assert(n == 0);
        cout << "join:" << iter->namebuffer << " suceesss , number : " << (long long)ret << endl;
        cout.flush();
        delete iter;
    }
    cout << "join end" << endl;
    // while (true)
    // {
    //     cout << "main thread " << endl;
    //     sleep(1);
    // }
    return 0;
}

// // void *start_routine(void *argv)
// // {
// //     string name = static_cast<const char *>(argv);
// //     while (true)
// //     {
// //         cout << "thread name is : " << name << endl;
// //         // sleep(1);
// //     }
// // }

// // int main()
// // {
// //     vector<pthread_t> vp;
// // #define NUM 10
// //     for (size_t i = 0; i < NUM; ++i)
// //     {
// //         pthread_t tid;
// //         char namebuffer[64];
// //         snprintf(namebuffer, sizeof(namebuffer), "%s:%d", "thread", i);
// //         // pthread_create(&tid, nullptr, start_routine, (void *)"thread 1");
// //         pthread_create(&tid, nullptr, start_routine, namebuffer);
// //         // sleep(1);
// //     }
// //     while (true)
// //     {
// //         cout << "thread name is :main thread " << endl;
// //         // sleep(1);
// //     }
// //     return 0;
// // }

// // 一个线程出问题了，会影响其他线程吗？
// // void *start_routine(void *argv)
// // {
// //     string name = static_cast<const char *>(argv);
// //     while (1)
// //     {
// //         cout << "thread name is : " << name << endl;
// //         sleep(1);
// //         int *p = nullptr;
// //         //*p=nullptr //会报错 —— 类型不匹配
// //         *p = 0;
// //     }
// // }

// // int main()
// // {
// //     pthread_t id;
// //     pthread_create(&id, nullptr, start_routine, (void *)"thread 1"); // 最后一个参数要强转
// //     while (1)
// //     {
// //         cout << "thread name is :main thread " << endl;
// //         sleep(1);
// //     }
// //     return 0;
// // }

// // int main()
// // {
// //     // 1. 我们想创建一批线程
// //     vector<ThreadDate*> threads;
// // #define NUM 10
// //     for(int i = 0; i < NUM; i++)
// //     {
// //         ThreadDate *td = new ThreadDate();
// //         snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);
// //         pthread_create(&td->tid, nullptr, start_routine, td);
// //         threads.push_back(td);

// //         // pthread_create(&tid, nullptr, start_routine, (void*)"thread one");
// //         // pthread_create(&tid, nullptr, start_routine, namebuffer);
// //         // sleep(1);
// //     }

// //     for(auto &iter : threads)
// //     {
// //         cout << "create thread: " << iter->namebuffer << " : " << iter->tid << " suceesss" << endl;
// //     }

// //     while (true)
// //     {
// //         cout << "new thread create success, name: main thread" << endl;
// //         sleep(1);
// //     }
// //     return 0;
// // }